package com.lvideo.component.extraplayer.videoview;

import android.app.Activity;
import android.content.Context;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.MediaController;
import android.widget.TextView;

import com.letv.sdk.callbacks.LetvPlayerView;
import com.lvideo.component.extraplayer.Interface.MyAdStatusListener;
import com.lvideo.component.extraplayer.LVideoMediaPlayerControl;
import com.lvideo.component.extraplayer.utils.MyPlayerConstant;
import com.media.ffmpeg.FFMpegPlayer;
import com.novaplayer.info.PlayUrl;
import com.novaplayer.listener.OnSubtitleListener;
import com.novaplayer.listener.OnVideoViewStateChangeListener;
import com.pplive.player.PPTVPlayerStatusListener;
import com.pplive.sdk.PPTVSdkMgr;
import com.pplive.sdk.PPTVSdkParam;
import com.pplive.videoplayer.BasePlayerStatusListener;
import com.pplive.videoplayer.PPTVVideoView;
import com.tencent.qqlive.mediaplayer.api.TVK_PlayerVideoInfo;
import com.tencent.qqlive.mediaplayer.api.TVK_UserInfo;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import static com.lvideo.component.extraplayer.utils.MyPlayerConstant.DEFINITION_HIGH;

/**
 * Created by zhaopeipei on 2017/1/11.
 */
public class VideoViewPPTVProxy implements LVideoMediaPlayerControl {

    private Context mContext;

    private LinkedHashMap<String, Integer> map;

    private static final int ON_AD_VISIBLE = 1000;
    private static final int ON_AD_COUNT_DOWN = 2000;
    private static final int ON_REPLAY = 3000;

    public static final int PE_DEFINITION_LOW_400 = 0;
    public static final int PE_DEFINITION_LOW_300 = 5;
    public static final int PE_DEFINITION_LOW_150 = 6;
    public static final int PE_DEFINITION_HIGH = 1;
    public static final int PE_DEFINITION_SUPER = 2;
    public static final int PE_DEFINITION_BLUE = 3;

    private MediaPlayer.OnPreparedListener mOnPreparedListener;
    private MediaPlayer.OnSeekCompleteListener mOnSeekCompleteListener;
    private MediaPlayer.OnCompletionListener mOnCompletionListener;
    private MediaPlayer.OnErrorListener mOnErrorListener;
    private MediaPlayer.OnInfoListener mOnInfoListener;
    private MyAdStatusListener mOnAdStatusListener;

    private MediaPlayer.OnVideoSizeChangedListener mOnVideoSizeChangedListener;
    private MediaPlayer.OnBufferingUpdateListener mOnBufferingUpdateListener;
    private OnVideoViewStateChangeListener mOnVideoViewStateChangeListener;

    protected PPTVVideoView mVideoView = null;

    private View mAdView;

    private String param;

    private ImageView mAdImageView;

    private ImageView mAdImageViewClose;

    private TextView mAdCountText;

    private String mUrl = "";

    private int mStatus = BasePlayerStatusListener.STATUS_NEW_START;

    private int mSeekTime = 0;

    private boolean canSeek = false;

    private boolean isPlaying = false;
    private boolean isPlayingAd = false;

    private boolean isPreparing = false;

    private int mFluencyPptvFt = -1;

    private int firstErrorCode = 0;

    public VideoViewPPTVProxy(Context context){
        this.mContext = context;
        map = new LinkedHashMap();
    }

    private Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what)
            {
                case ON_AD_VISIBLE: {
                    if (mAdView != null) {
                        mAdView.setVisibility(View.VISIBLE);
                    }
                    mAdCountText.setVisibility(View.VISIBLE); //set visible in player_ad_view.xml
                    break;
                }
                case ON_AD_COUNT_DOWN: {
                    String s = (String)msg.obj;
                    mAdCountText.setText(s);
                    break;
                }
                case ON_REPLAY: {
                    PPTVSdkMgr.getInstance().replay();
                    break;
                }
            }
        }

    };

    @Override
    public void setVideoPlayUrl(PlayUrl url) {

    }

    @Override
    public void setVideoPath(String videoPath) {

    }

    @Override
    public void setVideoPath(String videoPath, Map<String, String> headers) {

    }

    @Override
    public View getView() {
        return mVideoView;
    }

    public void setPptvScreenView(View adView, ImageView iamgeView, TextView textView,
                                  Activity activity) {
        mAdView = adView;
        mAdImageView = iamgeView;
        mAdCountText = textView;
    }

    public void initPptv() {
        mVideoView = new PPTVVideoView(mContext);
        if (mAdImageView != null) {
            PPTVSdkMgr.getInstance().initVideoView(mContext, mVideoView, mAdImageView);
        }
        PPTVSdkMgr.getInstance().setOnPlayerStatusListener(listener);
    }

    public void setPptvDataSource(String url, int start) {
        mUrl = url;
        mSeekTime = start;
    }

    @Override
    public boolean isSohuAdvertInPlayback() {
        return isPlayingAd;
    }

    @Override
    public void start() {
        try {
            if (isPreparing) {
                return;
            }
            play();
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }


    private void play() {
        if (mStatus == BasePlayerStatusListener.STATUS_PLAY_PAUSE) {
            PPTVSdkMgr.getInstance().resume();
            return;
        }
        String url = mUrl;
        try {
            url = URLEncoder.encode(url, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
        String param = String.format("%s=%s&%s=%s", PPTVSdkParam.Player_Ft, "0", PPTVSdkParam.Player_Encodeurl, url);
        if (mSeekTime > 0) {
            param = String.format("%s&%s=%d", param, PPTVSdkParam.Player_SeekTime, mSeekTime);
        }
        try {
            PPTVSdkMgr.getInstance().play(mContext, param);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public void next() {
    }

    @Override
    public void setTencentData(TVK_UserInfo userinfo, TVK_PlayerVideoInfo playerinfo, int currPlayTime) {

    }

    @Override
    public void setLetvScreenView(LetvPlayerView letvScreenView) {

    }

    @Override
    public void setLetvData(long vid,int currPlayTime) {

    }

    @Override
    public void setBestvData(String vid, String fdnCode, long currPlayTime) {

    }

    @Override
    public int getFirstErrorCode() {
        return firstErrorCode;
    }

    @Override
    public void playVideoAt(int index) {
    }

    @Override
    public void pause() {
        PPTVSdkMgr.getInstance().pause();
    }

    @Override
    public int getDuration() {
        return (int)PPTVSdkMgr.getInstance().getDuration() * 1000;
    }

    @Override
    public int getCurrentPosition() {
        return (int)PPTVSdkMgr.getInstance().getRelTime() * 1000;
    }

    @Override
    public void stopPlayback() {
        PPTVSdkMgr.getInstance().stop(false);
    }

    @Override
    public void seekTo(int pos) {
        PPTVSdkMgr.getInstance().seek(pos / 1000);
        mSeekTime = pos / 1000;
        if (mOnSeekCompleteListener != null) {
            mOnSeekCompleteListener.onSeekComplete(null);
        }
    }

    @Override
    public boolean isPlaying() {
        return isPlaying || isPlayingAd;
    }

    @Override
    public int getBufferPercentage() {
        return 0;
    }

    @Override
    public boolean canSeekForward() {
        return true;
    }

    @Override
    public int getAudioSessionId() {
        return 0;
    }

    @Override
    public boolean canSeekBackward() {
        return true;
    }

    @Override
    public void forward() {

    }

    @Override
    public void rewind() {

    }

    @Override
    public void adjust(int type) {

    }

    @Override
    public MediaPlayer getMediaPlayer() {
        return null;
    }


    @Override
    public int getLastSeekWhenDestoryed() {
        return 0;
    }

    @Override
    public boolean isPaused() {
        return false;
    }

    @Override
    public boolean canPause() {
        return true;
    }

    @Override
    public void setMediaController(MediaController var1) {

    }

    @Override
    public boolean isInPlaybackState() {
        return false;
    }

    @Override
    public void setOnPreparedListener(MediaPlayer.OnPreparedListener var1) {
        mOnPreparedListener = var1;
    }

    @Override
    public void setOnCompletionListener(MediaPlayer.OnCompletionListener var1) {
        mOnCompletionListener = var1;
    }

    @Override
    public void setOnInfoListener(MediaPlayer.OnInfoListener var1) {
        mOnInfoListener = var1;
    }

    @Override
    public void setOnErrorListener(MediaPlayer.OnErrorListener var1) {
        mOnErrorListener = var1;
    }

    @Override
    public void setOnAdListener(MyAdStatusListener var) {
        mOnAdStatusListener = var;
    }

    @Override
    public void setOnSeekCompleteListener(MediaPlayer.OnSeekCompleteListener var1) {
        mOnSeekCompleteListener = var1;
    }

    @Override
    public void setOnVideoSizeChangedListener(MediaPlayer.OnVideoSizeChangedListener var1) {
        this.mOnVideoSizeChangedListener = var1;
    }

    @Override
    public void setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener l) {
        this.mOnBufferingUpdateListener = l;
    }

    @Override
    public void setVideoViewStateChangeListener(OnVideoViewStateChangeListener videoViewStateChangeListener) {
        mOnVideoViewStateChangeListener = videoViewStateChangeListener;
    }

    @Override
    public void setOnSubtitleListener(OnSubtitleListener onSubtitleListener) {

    }

    @Override
    public void setInitPosition(int i) {

    }

    @Override
    public void switchStreamSource(String s, int i, int i1) {

    }

    @Override
    public int setSourceType(int i) {
        return 0;
    }

    @Override
    public void setParameter(int i, Object o) {

    }

    @Override
    public boolean handleTouchEvent(MotionEvent motionEvent) {
        return false;
    }

    @Override
    public void usingSensor(int i, boolean b) {

    }

    @Override
    public void setLanguage(String s) {

    }

    @Override
    public String[] getLanguage() {
        return new String[0];
    }

    @Override
    public void setOnAdNumberListener(FFMpegPlayer.OnAdNumberListener var1) {

    }

    @Override
    public void setOnBlockListener(FFMpegPlayer.OnBlockListener var1) {

    }

    @Override
    public void setOnHardDecodeErrorListener(FFMpegPlayer.OnHardDecodeErrorListner var1) {

    }

    @Override
    public boolean isEnforcementWait() {
        return false;
    }

    @Override
    public void setEnforcementWait(boolean var1) {

    }

    @Override
    public boolean isEnforcementPause() {
        return false;
    }

    @Override
    public void setEnforcementPause(boolean var1) {

    }

    @Override
    public void setCacheSize(int var1, int var2, int var3, int var4) {

    }


    private BasePlayerStatusListener listener = new PPTVPlayerStatusListener() {
        /**
         * @brief 广告剩余时间倒计时，不需额外进行Timer任务等来循环显示
         * @param[in] remain 剩余时间
         */
        @Override
        public void onAdCountDown(int remain) {
            String s = "广告剩余" + remain + "秒";
            Log.e("pptv", "AdCountDown " + s);
            Message msg = mHandler.obtainMessage(ON_AD_COUNT_DOWN);
            msg.obj = s;
            mHandler.sendMessage(msg);
        }

        /**
         * @brief 广告播放错误
         * @param[in] what 播放错误码。播放器播放错误则使用Android系统提供的错误码，其他环节（如加载广告时）的错误请参照PPTVVideoView类
         * @param[in] extra 额外信息
         */
        @Override
        public void onAdError(final int what, final int extra) {
            isPlayingAd = false;
            ((Activity)mContext).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (mOnAdStatusListener != null) {
                        mOnAdStatusListener.onAdError(what, extra);
                    }
                }
            });
        }

        /**
         * @brief 广告播放完成
         */
        @Override
        public void onAdFinished() {
            Log.e("pptv", "AdFinished ");
            isPlayingAd = false;
            mAdView.setVisibility(View.GONE);
            ((Activity)mContext).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (mOnAdStatusListener != null) {
                        mOnAdStatusListener.onAdFinished();
                    }
                }
            });
        }

        /**
         * @brief 广告加载中
         */
        @Override
        public void onAdLoading() {
            Log.e("pptv", "AdLoading ");
            isPreparing = false;
        }

        /**
         * 广告播放开始。只在第一个广告开始播放时被被调用一次
         */
        @Override
        public void onAdStarted() {
            Log.e("pptv", "AdStarted ");
            isPlayingAd = true;
            isPreparing = false;
            Message msg = mHandler.obtainMessage(ON_AD_VISIBLE);
            mHandler.sendMessage(msg);
            ((Activity)mContext).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (mOnAdStatusListener != null) {
                        mOnAdStatusListener.onAdStarted();
                    }
                }
            });
        }

        /**
         * @brief 广告大小改变事件
         * @param[in] width 表示当前广告宽度
         * @param[in] height 表示当前广告高度
         */
        @Override
        public void onAdSizeChanged(int width, int height) {
        }

        @Override
        public void onGotFirstKeyFrame() {
            ((Activity)mContext).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (mOnInfoListener != null) {
                        mOnInfoListener.onInfo(null, MyPlayerConstant.START_TO_PLAY, 0);
                    }
                }
            });
        }

        /**
         * @brief 广告WebView 显示或隐藏
         * @param[in] show 1表示可见，0表示隐藏
         */
        @Override
        public void onAdWebViewVisibleChanged(int show) {

        }

        /**
         * @brief 视频缓冲进度
         * @param[in] percent 表示缓冲进度，0-100
         */
        @Override
        public void onBufferingUpdate(int percent) {
        }

        /**
         * @brief 开始缓冲视频
         */
        @Override
        public void onBufferStart() {
            ((Activity)mContext).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (mOnInfoListener != null) {
                        mOnInfoListener.onInfo(null, MediaPlayer.MEDIA_INFO_BUFFERING_START, 0);
                    }
                }
            });
        }

        /**
         * @brief 缓存完成
         */
        @Override
        public void onBufferEnd() {
            ((Activity)mContext).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (mOnInfoListener != null) {
                        mOnInfoListener.onInfo(null, MediaPlayer.MEDIA_INFO_BUFFERING_END, 0);
                    }
                }
            });
        }

        /**
         * @brief 视频播放完成
         */
        @Override
        public void onCompletion() {
            Log.e("pptv", "onCompletion " + getCurrentPosition() / 1000);
            canSeek = false;
            isPlaying = false;
            isPreparing = false;
            ((Activity)mContext).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (mOnCompletionListener != null && Math.abs(getCurrentPosition() - getDuration()) <= 5000) {
                        mOnCompletionListener.onCompletion(null);
                    }
                }
            });
        }

        /**
         * @brief 播放发生错误时，报告错误，play url或者不支持播放。
         * @param[in] err PPTV错误代码，例如 PPTVVideoView.ERROR_NETWORK
         * @param[in] what 播放器错误代码
         * @param[in] extra an extra code, specific to the error. Typically implementation dependant.
         * @see [类、类#方法、类#成员]
         */
        @Override
        public void onError(int err, int what, int extra) {
            Log.e("pptv_sdk", "onError: err=" + err + ", what=" + what + ", extra=" + extra);
            canSeek = false;
            isPlaying = false;
            isPreparing = false;
            final int tErr = err;
            final int tWhat = what;
            final int tExtra = extra;

            ((Activity)mContext).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (mOnErrorListener != null) {
                        firstErrorCode = tErr;
                        mOnErrorListener.onError(null, tWhat, tExtra);
                    }
                }
            });
        }

        /**
         * @brief 在播放和切换下一集的时候，需要加载和加载结束之间。
         * @param[in] show 是否显示
         */
        @Override
        public void onLoading(boolean show) {
        }

        /**
         * @brief 准备好播放视频
         */
        @Override
        public void onPrepared() {
            long duration = PPTVSdkMgr.getInstance().getDuration();
            Integer default_ft = PPTVSdkMgr.getInstance().getCurrentFt();
            Integer default_scale = PPTVSdkMgr.getInstance().getCurrentScaleType();
            canSeek = true;
            isPreparing = true;
            ((Activity)mContext).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (mOnPreparedListener != null) {
                        mOnPreparedListener.onPrepared(null);
                    }
                }
            });
            Log.e("pptv_sdk", "onPrepared: totaltime=" + duration + ", default_ft=" + default_ft + ", default_scale=" + default_scale);
        }

        /**
         * @brief 播放的进度改变
         * @param[in] currentPosition 表示当前时间，单位秒
         * @param[in] duration 表示总时长，单位秒
         */
        @Override
        public void onProgressUpdate(int current, int duration) {
        }

        /**
         * @brief 视频被暂停
         */
        @Override
        public void onPaused() {
        }

        /**
         * @brief 清晰度改变
         * @param[in] resolution 表示当前清晰度类型
         */
        @Override
        public void onResolutionChanged(int resolution) {

        }

        /**
         * @brief 视频开始播放
         */
        @Override
        public void onStarted() {
            isPlaying = true;
            isPreparing = false;
        }

        /**
         * @brief 视频被停止播放
         */
        @Override
        public void onStoped() {
            isPlaying = false;
        }

        /**
         * 用户检索
         */
        @Override
        public void onSeekStartFromUser() {
        }

        /**
         * @brief 用户检索完成
         * @param[in] current 表示当前检索位置，单位秒
         * @param[in] duration 表示总时长，单位秒
         */
        @Override
        public void onSeekComplete(int current, int duration) {
//            mBufferProgress.setVisibility(View.GONE);
        }

        /**
         * @brief 视频大小改变
         * @param[in] width 表示当前视频宽度
         * @param[in] height 表示当前视频高度
         */
        @Override
        public void onSizeChanged(int width, int height) {

        }

        /**
         * @brief 通知VideoView所处的状态，正在取得详细信息，正在获取跳转URL还是开始播放。
         * @param[in] status 播放状态
         * @see PPTVVideoView.STATUS_BUFFER_END
         * @see PPTVVideoView.STATUS_PLAY_START
         */
        @Override
        public void onStatus(int status) {
            Log.e("pptv_sdk", "onStatus: status=" + mStatus + ", new status=" + status);
            if (status == BasePlayerStatusListener.STATUS_BUFFER_START || status == BasePlayerStatusListener.STATUS_BUFFER_END) {
                return;
            }
            //断网重连
            if (status == BasePlayerStatusListener.STATUS_NETWORK_CONNECTED && mStatus == BasePlayerStatusListener.STATUS_PLAY_UNCOMPLETED) {
                mHandler.sendEmptyMessage(ON_REPLAY);
                return;
            }
            mStatus = status;
            if (mStatus == BasePlayerStatusListener.STATUS_PLAY_START) {
                isPlaying = true;
            }
            else if (mStatus == BasePlayerStatusListener.STATUS_PLAY_PAUSE) {
                isPlaying = false;
            }
            else if (mStatus == BasePlayerStatusListener.STATUS_PLAY_FINISH ||
                    mStatus == BasePlayerStatusListener.STATUS_PLAY_STOP) {
                isPlaying = false;
            }
        }
    };

    //pptvsdk播放的清晰度
    //* @brief 清晰度: FT_LOW_150=6,FT_LOW_300=5,FT_MIDDLE_400=0,FT_MIDDLE_600=1,FT_HIGH=2,FT_BD=3,FT_UNKNOWN=-1
    //* @brief 分类: -1表示未知清晰度，0/5/6都表示流畅，1表示高清，2表示超清，3表示蓝光

    public List<Integer> getSupportDefinitions() {
        List<Integer> pptvFtList = PPTVSdkMgr.getInstance().getFtList();
        List<Integer> myFtList = new ArrayList<Integer>();
        for (Integer ft:pptvFtList){
            if(!myFtList.contains(DEFINITION_HIGH) && (ft==0 || ft==5 || ft==6 )){
                mFluencyPptvFt = ft;
                myFtList.add(DEFINITION_HIGH);
            }else if(ft==1){
                myFtList.add(MyPlayerConstant.DEFINITION_SUPER);
            }else if(ft==2){
                myFtList.add(MyPlayerConstant.DEFINITION_SUPER2);
            }else if(ft==3){
                myFtList.add(MyPlayerConstant.DEFINITION_REAL);
            }
        }
        return myFtList;
    }

    @Override
    public void changeDefinition(int definition){
        int pptvFt = -1;
        if(definition==MyPlayerConstant.DEFINITION_REAL){
            pptvFt = 3;
        }else if(definition==MyPlayerConstant.DEFINITION_SUPER2){
            pptvFt=2;
        }else if(definition==MyPlayerConstant.DEFINITION_SUPER){
            pptvFt=1;
        }else if(definition== DEFINITION_HIGH){
            pptvFt=mFluencyPptvFt;
        }
        if(pptvFt != -1){
            PPTVSdkMgr.getInstance().changeFt(pptvFt);
        }
    }

    @Override
    public int getCurrentDefinition() {
        int pptvFt = PPTVSdkMgr.getInstance().getCurrentFt();
        int myFt = DEFINITION_HIGH;
        if(pptvFt==0 || pptvFt==5 || pptvFt==6 ){
            myFt = DEFINITION_HIGH;
        }else if(pptvFt==1){
            myFt = MyPlayerConstant.DEFINITION_SUPER;
        }else if(pptvFt==2){
            myFt = MyPlayerConstant.DEFINITION_SUPER2;
        }else if(pptvFt==3){
            myFt = MyPlayerConstant.DEFINITION_REAL;
        }
        return myFt;
    }

    @Override
    public void onDestroyData() {
        mAdView = null;
        mVideoView = null;
    }
}
